package nci60.data.maxquant.msms
import nci60.data.maxquant.RawFile
import nci60.data.maxquant.Project
import org.apache.commons.lang3.builder.HashCodeBuilder

/**
 * Full Ms/Ms spectrum from apl file <p />
 * This class has an composite primary key instead of an id property <p />
 * The key is composed of {@link #currentProject}, {@link #rawFile} and {@link #scanNumber} <p />
 * <b>See Also:</b> {@link #mapping}
 * 
 * @autor <a href="mailto:Florian.J.Auer@googlemail.com">Florian J. Auer</a>
*/
class FullSpectrum implements Serializable {

    /**
    * reference to the RAW file the mass spectral data was read from <p />
    * @see nci60.data.maxquant.RawFile
    */
    RawFile rawFile
    
    /**
    * The RAW-file derived scan number of the MS/MS spectrum
    */
    Integer scanNumber
    
    /**
    * reference to the analysis it belongs to <p />
    * @see nci60.data.maxquant.Project
    */
    Project currentProject
    
    /**
    * Detected masses, separated by semicolons <p />
    * The property has a customized mapping as "text" <p />
    * <b>See Also:</b> {@link #mapping}
    */
    String masses
    
    /**
    * Detected intensities, separated by semicolons <p />
    * The property has a customized mapping as "text" <p />
    * <b>See Also:</b> {@link #mapping}
    */
    String intensities

    /**
     * GRAILS <a href="http://grails.org/doc/latest/guide/single.html#constraints" target="_blank">Declaring Constraints</a>
     * <p />
     * Constraints in Grails are a way to declaratively specify validation rules for generating objects in GORM.
     */	
    static constraints = {
    }

    /**
     * GRAILS <a href="http://grails.org/doc/latest/guide/GORM.html#ormdsl" target="_blank">Custom ORM Mapping</a>
     * <p />
     * Grails domain classes can be mapped onto many legacy schemas with an Object Relational Mapping DSL (domain specific language). 
     */	
    static mapping = {
        version false
        id composite: ['currentProject', 'rawFile', 'scanNumber']
        masses type: 'text'
        intensities type: 'text'
    }

    /**
     * Overwrites the default method for comparing two domain classes <p />
     * This is necessary for composite primary key
     * 
     * @param   other some other object which is compared to
     * @return  is true if both are equal
     */
    boolean equals(other) {
        if (!(other instanceof FullSpectrum)) {
            return false
        }

        other.currentProject == currentProject && other.rawFile == rawFile && other.scanNumber == scanNumber
    }

    /**
     * Overwrites the default method for generating a hash code <p />
     * This is necessary for composite primary key
     * 
     * @return  hash code for primary key
     */
    int hashCode() {
        def builder = new HashCodeBuilder()
        builder.append currentProject
        builder.append rawFile
        builder.append scanNumber
        builder.toHashCode()
    }
}
